
#include "ByteSerializer.h"
#include "HashFunctions.h"

using namespace ttg;
using namespace ttg::extras::serialization;
using namespace ttg_internal::extras::serialization;

//----------------------
//--- ByteSerializer ---
//----------------------

void ByteSerializer::prepareData(size_t inc_size)
{
	if ((data.size() - DEFAULT_SIZE) % DEFAULT_INC < inc_size)
		data.reserve(data.size() + DEFAULT_INC);
}

void ByteSerializer::writeHash(unsigned __int32 hash)
{
	for (size_t i = 0; i < 4; i++)
		this->data.push_back(((unsigned char *)&hash)[i]);
}

void ByteSerializer::serializeMemory(const void *data, size_t size, const char *name)
{
	if (is_safe)
	{
		prepareData(size + 4);
		writeHash(hashFunc(name, size) << 2);
	}
	else
		prepareData(size);
	//Serializing raw value.
	for (size_t i = 0; i < size; i++)
		this->data.push_back(((const unsigned char *)data)[i]);
}

void ByteSerializer::serializeReferenceStart(bool is_null, const char *name)
{
	if (is_safe)
	{
		prepareData(4);
		writeHash((hashFunc(name, 0) << 2) | (is_null ? 2 : 1));
	}
	else
	{
		prepareData(1);
		this->data.push_back(is_null ? NullReferenceFlag : NotNullReferenceFlag);
	}
}

void ByteSerializer::serializeReferenceEnd()
{
	if (is_safe)
	{
		prepareData(1);
		data.push_back(ReferenceEnd);
	}
}

ByteSerializer::ByteSerializer(bool is_safe)
	:data(0)
{
	data.reserve(DEFAULT_SIZE);
	this->is_safe = is_safe;
	data.push_back(is_safe ? SafeSerialization : NotSafeSerialization);
}
